﻿using Seggu.Dtos;
using Seggu.Infrastructure;
using Seggu.Services.Interfaces;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System.Data;

namespace Seggu.Desktop.Forms
{
    public partial class Compañías : Form
    {
        private ICompanyService companyService;
        private IProducerService producerService;
        private IRiskService riskService;
        private ICoveragesPackService coveragesPackService;
        private ICoverageService coverageService;
        private IMasterDataService masterDataService;
        private CompanyFullDto selectedFullCompany;
        private CompanyDto currentCompany;
        private int lastCompanyIndex;

        public Compañías(ICompanyService companyService, ICoverageService coverageService,
            ICoveragesPackService coveragesPackService, IProducerService producerService, 
            IRiskService riskService, IMasterDataService masterDataService)
        {
            InitializeComponent();
            this.companyService = companyService;
            this.producerService = producerService;
            this.riskService = riskService;
            this.coveragesPackService = coveragesPackService;
            this.coverageService = coverageService;
            this.masterDataService = masterDataService;
            this.InitializeIndex();
        }    
        private void InitializeIndex()
        {
            lastCompanyIndex = grdCompañias.CurrentCell == null? 0 : grdCompañias.CurrentCell.RowIndex;
            lsbRiesgos.DataSource = null;
            grdCoveragesPack.DataSource = null;
            lsbCoberturas.DataSource = null;
            grdCompañias.DataSource = companyService.GetAll().ToList();
            FormatCompanyGrid();
            PopulateComboboxes();
            grdCompañias.CurrentCell = grdCompañias.Rows[lastCompanyIndex].Cells["Name"];
        }
            private void FormatCompanyGrid()
            {
                foreach (DataGridViewColumn c in grdCompañias.Columns)
                    c.Visible = false;
                grdCompañias.Columns["Name"].Visible = true;
                grdCompañias.Columns["Name"].HeaderText = "Nombre";
            }
            private void PopulateComboboxes()
            {
                cmbProductores.ValueMember = "Id";
                cmbProductores.DisplayMember = "Name";
                cmbProductores.DataSource = producerService.GetProducers().ToList();

                cmbTipoRiesgos.ValueMember = "Id";
                cmbTipoRiesgos.DisplayMember = "Name";
                cmbTipoRiesgos.DataSource = masterDataService.GetRiskTypes().ToList();
            }

        private void grdCompañias_SelectionChanged(object sender, EventArgs e)
        {
            PopulateForm();
        }
        private void grdCompañias_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            PopulateForm();
        }
            private void PopulateForm()
            {
                if (!grdCompañias.Focused) return;
                lsbCoberturas.DataSource = null;
                grdCoveragesPack.DataSource = null;
                currentCompany = (CompanyDto)grdCompañias.CurrentRow.DataBoundItem;
                BindCompaniesTextBoxes(currentCompany);

                selectedFullCompany = companyService.GetFullById(currentCompany.Id);
                if (selectedFullCompany.Contacts != null)
                    FillGrdContactos();
                if (selectedFullCompany.Producers != null)
                    FillGrdProductores();
                if (selectedFullCompany.Risks != null)
                    FillLsbRiesgos();
            }
                private void BindCompaniesTextBoxes(CompanyDto company)
                {
                    txtNombre.DataBindings.Clear();
                    txtLiq1.DataBindings.Clear();
                    txtLiq2.DataBindings.Clear();
                    txtConvenio1.DataBindings.Clear();
                    txtConvenio2.DataBindings.Clear();
                    txtMail.DataBindings.Clear();
                    txtNotas.DataBindings.Clear();
                    txtTelefono.DataBindings.Clear();
                    txtCUIT.DataBindings.Clear();

                    txtNombre.DataBindings.Add("text", company, "Name");
                    txtLiq1.DataBindings.Add("text", company, "LiqDay1");
                    txtLiq2.DataBindings.Add("text", company, "LiqDay2");
                    txtConvenio1.DataBindings.Add("text", company, "Convenio1");
                    txtConvenio2.DataBindings.Add("text", company, "Convenio2");
                    txtMail.DataBindings.Add("text", company, "Mail");
                    txtNotas.DataBindings.Add("text", company, "Notes");
                    txtTelefono.DataBindings.Add("text", company, "Phone");
                    txtCUIT.DataBindings.Add("text", company, "CUIT");
                }
                private void FillGrdContactos()
                {
                    this.grdContactos.DataSource = selectedFullCompany.Contacts;
                    this.grdContactos.Columns["Id"].Visible = false;
                    this.grdContactos.Columns["CompanyId"].Visible = false;
                    this.grdContactos.Columns["Bussiness"].Visible = false;
                }
                private void FillGrdProductores()
                {
                    this.grdProductores.DataSource = selectedFullCompany.Producers;
                    this.grdProductores.Columns["Id"].Visible = false;
                }
                private void FillLsbRiesgos()
                {
                    if (selectedFullCompany == null) return;
                    lsbRiesgos.ValueMember = "Id";
                    lsbRiesgos.DisplayMember = "Name";
                    lsbRiesgos.DataSource = selectedFullCompany.Risks
                        .Where(r => r.RiskType == cmbTipoRiesgos.SelectedValue.ToString()).ToList();
                }

        private void btnGuardar_Click(object sender, EventArgs e)
        {
            lblNuevaCompañia.Visible = false;
            btnAgregarCompañia.UseVisualStyleBackColor = true;

            if (ValidateControls())
            {
                CompanyDto company;
                if (grdCompañias.DataSource == null)
                {
                    company = this.GetFormData();
                    this.companyService.Create(company);
                }
                else
                {
                    company = (CompanyDto)grdCompañias.CurrentRow.DataBoundItem;
                    this.companyService.Update(company);
                }
                btnEditar_Click(sender, e);
                InitializeIndex();
            }
        }
            private bool ValidateControls()
            {
                bool ok = true;
                errorProvider1.Clear();
                foreach (Control control in grpbDatos.Controls)
                {
                    if (control == txtNombre || control == txtTelefono || control == txtMail)
                    {
                        if (control.Text == string.Empty)
                        {
                            errorProvider1.SetError(control, "Campo vacío");
                            ok = false;
                        }
                    }
                }
                return ok;
            }
            private CompanyDto GetFormData()
            {
                var company = new CompanyDto();
                company.Active = true;
                company.CUIT = txtCUIT.Text;
                company.LiqDay1 = txtLiq1.Text;
                company.LiqDay2 = txtLiq2.Text;
                company.Mail = txtMail.Text;
                company.Name = txtNombre.Text;
                company.Notes = txtNotas.Text;
                company.Phone = txtTelefono.Text;
                return company;
            }

        private void cmbTipoRiesgos_SelectionChangeCommitted(object sender, EventArgs e)
        {
            lsbCoberturas.DataSource = null;
            grdCoveragesPack.DataSource = null;
            FillLsbRiesgos();
        }

        private void lsbRiesgos_SelectedValueChanged(object sender, EventArgs e)
        {
            if (lsbRiesgos.DataSource == null) return;
            FillgrdCoveragesPack();
            FillLsbCoberturas(true);
        }
            private void FillgrdCoveragesPack()
            {
                if (lsbRiesgos.SelectedValue == null) return;
                grdCoveragesPack.DataSource = coveragesPackService
                    .GetAllByRiskId(lsbRiesgos.SelectedValue.ToString()).ToList();
                FormatCoveragesPacksGrid();
                grdCoveragesPack.ClearSelection();
            }
                private void FormatCoveragesPacksGrid()
                {
                    foreach (DataGridViewColumn c in grdCoveragesPack.Columns)
                        c.Visible = false;
                    grdCoveragesPack.Columns["Name"].Visible = true;
                    grdCoveragesPack.Columns["Name"].HeaderText = "Nombre";
                }
        private void grdCoveragesPack_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            if (((CoveragesPackDto)grdCoveragesPack.CurrentRow.DataBoundItem).Coverages == null) return;
            FillLsbCoberturas(false);
        }
            private void FillLsbCoberturas(bool fromRisk)
            {
                lsbCoberturas.ValueMember = "Id";
                lsbCoberturas.DisplayMember = "Description";
                if (fromRisk)
                    lsbCoberturas.DataSource = coverageService
                        .GetAllByRiskId(lsbRiesgos.SelectedValue.ToString()).ToList();
                else
                    lsbCoberturas.DataSource = ((CoveragesPackDto)grdCoveragesPack.CurrentRow.DataBoundItem)
                        .Coverages.ToList();
                lsbCoberturas.ClearSelected();
            }

        private void btnNuevoProductor_Click(object sender, EventArgs e)
        {
            Forms.Productores form = (Productores)DependencyContainer.Instance.Resolve(typeof(Productores)); 
            form.Show();
        }
        
        private void btnEditar_Click(object sender, EventArgs e)
        {
            if (!btnGuardar.Visible)
            {
                btnGuardar.Visible = true;
                btnNuevoProductor.Visible = true;
                btnQuitarCobertura.Visible = true;
                btnQuitarRiesgo.Visible = true;
                btnQuitarCompañia.Visible = true;
                btnQuitarProductor.Visible = true;
                btnAgregarCompañia.Visible = true;
                btnAgregarCobertura.Visible = true;
                btnAgregarProd.Visible = true;
                btnAgregarRiesgos.Visible = true;
                btnAgregarPaquete.Visible = true;
                btnQuitarPaquete.Visible = true;
                btnInsertInPack.Visible = true;
                btnDeleteFromPack.Visible = true;
                txtCoveragesPack.Visible = true;
                cmbProductores.Visible = true;
                label8.Visible = true;
                txtCode.Visible = true;
                lblCodigo.Visible = true;
                btnRecuperar.Visible = true;
                txtRiesgo.Visible = true;
                txtCoberturas.Visible = true;
                txtNombre.ReadOnly = false;
                txtTelefono.ReadOnly = false;
                txtCUIT.ReadOnly = false;
                txtLiq1.ReadOnly = false;
                txtLiq2.ReadOnly = false;
                txtConvenio1.ReadOnly = false;
                txtConvenio2.ReadOnly = false;
                txtMail.ReadOnly = false;
                txtNombre.ReadOnly = false;
                txtNotas.ReadOnly = false;
                txtTelefono.ReadOnly = false;
            }
            else
            {
                btnGuardar.Visible = false;
                btnNuevoProductor.Visible = false;
                btnQuitarCobertura.Visible = false;
                btnQuitarRiesgo.Visible = false;
                btnQuitarCompañia.Visible = false;
                btnQuitarProductor.Visible = false;
                btnAgregarCompañia.Visible = false;
                btnAgregarCobertura.Visible = false;
                btnAgregarProd.Visible = false;
                btnAgregarRiesgos.Visible = false;
                btnAgregarPaquete.Visible = false;
                btnQuitarPaquete.Visible = false;
                btnInsertInPack.Visible = false;
                btnDeleteFromPack.Visible = false;
                txtCoveragesPack.Visible = false;
                cmbProductores.Visible = false;
                label8.Visible = false;
                txtCode.Visible = false;
                lblCodigo.Visible = false;
                btnRecuperar.Visible = false;
                txtRiesgo.Visible = false;
                txtCoberturas.Visible = false;
                txtNombre.ReadOnly = true;
                txtTelefono.ReadOnly = true;
                txtCUIT.ReadOnly = true;
                txtLiq1.ReadOnly = true;
                txtLiq2.ReadOnly = true;
                txtConvenio1.ReadOnly = true;
                txtConvenio2.ReadOnly = true;
                txtMail.ReadOnly = true;
                txtNombre.ReadOnly = true;
                txtNotas.ReadOnly = true;
                txtTelefono.ReadOnly = true;
            }
        }

        private void btnAgregarCompañia_Click(object sender, EventArgs e)
        {
            //limpiar todos los controles
            btnAgregarCompañia.BackColor = SystemColors.Highlight;
            lblNuevaCompañia.Visible = true;
            grdCompañias.DataSource = null;
            //lsbRiesgos.DataSource = riskService.GetAll().ToList();
            //lsbCoberturas.DataSource = coverageService.GetAll().ToList();
            //grdProductores.DataSource = producerService.GetProducers().ToList();
            grdContactos.DataSource = null;

            txtNombre.Clear();
            txtTelefono.Clear();
            txtCUIT.Clear();
            txtLiq1.Clear();
            txtLiq2.Clear();
            txtMail.Clear();
            txtNombre.Clear();
            txtNotas.Clear();
            txtTelefono.Clear();
        }
        private void btnQuitarCompañia_Click(object sender, EventArgs e)
        {

            DialogResult dialogResult = MessageBox.Show(
            "Esta acción NO será posible si alguna póliza existe con coberturas de esta compañía ¿Desea esto?", "Borrar Riesgos", MessageBoxButtons.YesNo);
            if (dialogResult == DialogResult.Yes)
            {
                try
                {
                    var obj = this.grdCompañias.CurrentRow.DataBoundItem;
                    var company = (CompanyDto)obj;
                    companyService.DeleteCompany(company);
                    InitializeIndex();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(
                    "Una excepcion ha llegado a la aplicacion. Por favor copiar el siguiente mensaje y consultar al equipo tecnico.\n" +
                    ex.Message + "\n" + ex.StackTrace + (ex.InnerException == null ? string.Empty : "\nInner Exception: " +
                    ex.InnerException.Message + "\nStackTrace: " +
                    ex.InnerException.StackTrace), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void btnAgregarProd_Click(object sender, EventArgs e)
        {
            if (txtCode.Text != "")
            {
                var prodCode = new ProducerCodeDto();
                prodCode.ProducerId = cmbProductores.SelectedValue.ToString();                
                prodCode.CompanyId = selectedFullCompany.Id;
                prodCode.Code = txtCode.Text;
                companyService.AddProducer(prodCode);
                InitializeIndex();
            }
            else
                errorProvider1.SetError(txtCode, "Campo vacío");
        }
        private void btnQuitarProductor_Click(object sender, EventArgs e)
        {
            string producerId = grdProductores.SelectedCells[3].Value.ToString();
            string companyId = selectedFullCompany.Id;
            companyService.DeleteProducerCode(producerId, companyId);
            InitializeIndex();
        }
        
        private void btnAgregarRiesgos_Click(object sender, EventArgs e)
        {
            if (txtRiesgo.Text!="")
            {
                var risk = new RiskCompanyDto();
                risk.CompanyId = currentCompany.Id;
                risk.Name = txtRiesgo.Text;
                risk.RiskType = cmbTipoRiesgos.SelectedItem.ToString();
                riskService.Create(risk);

                txtRiesgo.Text = "";
                InitializeIndex();
            }
        }
        private void btnQuitarRiesgo_Click(object sender, EventArgs e)
        {
            if (lsbRiesgos.Items.Count > 0)
            {
                DialogResult dialogResult = MessageBox.Show("Al quitar un RIESGO se eliminan todas sus coberturas. " +
                "NO será posible si alguna póliza existe con esa cobertura ¿Desea esto?", "Borrar Riesgos", MessageBoxButtons.YesNo);
                if (dialogResult == DialogResult.Yes)
                {
                    try
                    {
                        var riskId = lsbRiesgos.SelectedValue.ToString();
                        riskService.Delete(riskId);
                        var riesgos = (List<RiskCompanyDto>)this.lsbRiesgos.DataSource;
                        var risk = riesgos.FirstOrDefault(x => x.Id == riskId);
                        if (risk != null)
                            riesgos.Remove(risk);
                        InitializeIndex();
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(
                        "Una excepcion ha llegado a la aplicacion. Por favor copiar el siguiente mensaje y consultar al equipo tecnico.\n" +
                        ex.Message + "\n" + ex.StackTrace + (ex.InnerException == null ? string.Empty : "\nInner Exception: " +
                        ex.InnerException.Message + "\nStackTrace: " +
                        ex.InnerException.StackTrace), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
        }
       
        private void btnAgregarCobertura_Click(object sender, EventArgs e)
        {
            if ( txtCoberturas.Text !="")
            {
                var coverage = new CoverageDto();
                coverage.Description = txtCoberturas.Text;
                //coverage.Name = ? hardcode en dto mapper
                coverage.RiskId = lsbRiesgos.SelectedValue.ToString();
                coverageService.Save(coverage);
                txtCoberturas.Text = "";
                InitializeIndex();
            }
        }
        private void btnQuitarCobertura_Click(object sender, EventArgs e)
        {
            var coverages = lsbCoberturas.SelectedItems;
            if (lsbCoberturas.SelectedItems.Count > 0)
            {
                DialogResult dialogResult = MessageBox.Show("Si existen pólizas con esta cobertura producirá un error ¿avanzar?", "Borrar Cobertura", MessageBoxButtons.YesNo);
                if (dialogResult == DialogResult.Yes)
                {
                    coverageService.DeleteMany(coverages.Cast<CoverageDto>());
                    lsbCoberturas.DataSource = null;
                    InitializeIndex();
                }

            }
        }

        private void btnAgregarPaquete_Click(object sender, EventArgs e)
        {
            if (txtCoveragesPack.Text != "")
            {
                var coveragesPack = new CoveragesPackDto();
                coveragesPack.Name = txtCoveragesPack.Text;
                coveragesPack.RiskId = lsbRiesgos.SelectedValue.ToString();
                coveragesPack.Coverages = new List<CoverageDto>();
                coveragesPackService.Create(coveragesPack);
                txtCoveragesPack.Text = "";
                InitializeIndex();
            }
        }

        private void btnInsertInPack_Click(object sender, EventArgs e)
        {
            if (grdCoveragesPack.CurrentRow == null || lsbCoberturas.SelectedIndex == -1)
                return;

            var coveragesPack = (CoveragesPackDto)grdCoveragesPack.CurrentRow.DataBoundItem;
            foreach (CoverageDto coverage in lsbCoberturas.SelectedItems)
                coveragesPack.Coverages.Add(coverage);
            coveragesPackService.Update(coveragesPack);
        }
        private void btnDeleteFromPack_Click(object sender, EventArgs e)
        {
            if (grdCoveragesPack.CurrentRow == null || lsbCoberturas.SelectedIndex == -1)
                return;

            var coveragesPack = (CoveragesPackDto)grdCoveragesPack.CurrentRow.DataBoundItem;
            foreach (CoverageDto coverage in lsbCoberturas.SelectedItems)
                coveragesPack.Coverages.Remove(coverage);
            coveragesPackService.Update(coveragesPack);
        }
    }
}
